package com.g2room.myuall.grap.univ;

import java.io.IOException;
import java.net.MalformedURLException;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.g2room.myuall.grap.univ.po.UnivEnro;
import com.g2room.myuall.grap.univ.po.UnivInfoExtPo;
import com.g2room.myuall.grap.univ.po.UnivJudgement;
import com.g2room.myuall.grap.univ.po.UnivKeyMajor;
import com.g2room.myuall.grap.univ.po.UnivTeacher;
import com.g2room.myuall.util.DbUtil;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;

public class GrapUnivFromGKP implements Runnable {
	static String baseUrl = "http://gkcx.eol.cn";
	// 抓取各个专业
	private static String pageUrl = "http://www.gaokaopai.com/daxue-0-0-0-0-0-0-0--p-000.html";
//	static Map<String, Boolean> grapedUrls = getGrapedUrl();
	
	static List<String> sidList = new ArrayList<String>();
	static {
		sidList.add("http://www.gaokaopai.com/daxue-pjlist-2716.html");
	}
	
	public static void main(String[] args) {
//		int uid = 978;
		GrapUnivFromGKP gue = new GrapUnivFromGKP();
//		gue.getUnivInfo("http://www.gaokaopai.com/daxue-jianjie-"+uid+".html", uid);
//		gue.getBkzn(uid);
//		gue.getUnivTeacher("http://www.gaokaopai.com/daxue-shizi-"+uid+".html", uid);
//		gue.getPingjia("http://www.gaokaopai.com/daxue-pjlist-"+uid+".html", uid);
		/**
		 create table univ_info 

select a.*,b.doctoral_program,b.students,b.feature_major,b.key_subject,b.male,b.academician,b.female,b.master,b.attr
 from myuall.univ_info a,univ_info_ext b where a.name=b.schoolname
limit 10
		 */
		Integer uid = 0;
		for(String url : sidList) {
			// 12127 -- 12128
			uid = Integer.valueOf(url.split("-")[2].replace(".html", ""));
			gue.getPingjia(url, uid);
		}
		
//		for(int i =0; i<20; i++) {
//			try {
//				Thread.sleep(100);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			GrapUnivFromGKP gue = new GrapUnivFromGKP();
//			Thread t = new Thread(gue);
//			t.start();
//		}
	}

	@Override
	public void run() {
		List<String> listUrls = getUrl();
		if(null == listUrls) return;
		for(String url : listUrls) {
			getList(url);
		}
	}
	
	public static AtomicInteger page = new AtomicInteger(1);
	private static synchronized List<String> getUrl() {
		int l = 12;
		int max = 231;
		if(page.intValue() > max) return null;
		List<String> listUrls = new ArrayList<String>();
		for(int i = page.intValue(); i< page.intValue() + l; i++) {
			if(i>max) break;
			listUrls.add(pageUrl.replace("000", i+""));
		}
		page.addAndGet(l);
		return listUrls;
	}
	
	/**
	 * 获取分页列表数据
	 * @param url
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getList(String url) {
		Document doc = null;
		try {
			doc = new GenericMyuall().getDoc(url);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 1, e1.getMessage());
			return;
		}
		if(null == doc) return;
		List<String> uids = new ArrayList<String>();
		try {
			Elements aels = doc.getElementsByAttributeValue("class", "tit");
			for(Element ael : aels) {
				Element el = ael.getElementsByTag("a").first();
				String href = el.attr("href");
				// http://www.gaokaopai.com/daxue-jianjie-2658.html
				String[] uid = href.split("-");
				if(uid.length>1) {
					uids.add(uid[2].replace(".html", ""));
				} else {
					System.out.println("===="+href);
					System.out.println("");
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 2, e1.getMessage());
		}
		for(String sid : uids) {
			int uid = Integer.valueOf(sid);
			getUnivInfo("http://www.gaokaopai.com/daxue-jianjie-"+uid+".html", uid);
			getBkzn(uid);
			getUnivTeacher("http://www.gaokaopai.com/daxue-shizi-"+uid+".html", uid);
			getPingjia("http://www.gaokaopai.com/daxue-pjlist-"+uid+".html", uid);
		}
	}
	
	/**
	 * 获取分页列表数据
	 * @param url
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getBkzn(int uid) {
		// 型类：1、招生章程；2、自主招生；3、保送生招生；4、特长生招生。
		getZsContent("http://www.gaokaopai.com/daxue-zhinan-"+uid+".html", uid, 1);
		getZsContent("http://www.gaokaopai.com/daxue-zizhuzhaosheng-"+uid+".html", uid, 2);
		getZsContent("http://www.gaokaopai.com/daxue-baosongsheng-"+uid+".html", uid, 3);
		getZsContent("http://www.gaokaopai.com/daxue-techangsheng-"+uid+".html", uid, 4);
	}
	
	public void getPingjia(String url, int uid) {
		Document doc = null;
		try {
			doc = new GenericMyuall().getDoc(url);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 3, e1.getMessage());
			return;
		}
		if(null == doc) return;
		List<String> urls = new ArrayList<String>();
		try {
			Elements pageEls = doc.getElementsByAttributeValue("class", "pager");
			int pageNum = 0;
			if(null == pageEls || pageEls.isEmpty()) {
				getPjDetail(doc, uid);
				return;
			}
			Elements aels = pageEls.first().getElementsByTag("a");
			if(null != aels && !aels.isEmpty()) {
				// 获取最后一个分页数
				String pn = aels.get(aels.size() - 1).text();
				if(pn.contains("最后")) {
					Element lastEl = aels.get(aels.size() - 1);
					String href = lastEl.attr("href");
					// /daxue-pjlist-811-p-6.html
					pageNum = Integer.valueOf(href.split("-")[4].replace(".html", ""));
				} else {
					pageNum = Integer.valueOf(pn);
				}
				// 获取最后一个
				for(int i=1; i<=pageNum; i++) {
					urls.add("http://www.gaokaopai.com/daxue-pjlist-"+uid+"-p-"+i+".html");
				}
			} else {
				getPjDetail(doc, uid);
			}
			for(String pjUrl : urls) {
				getPjDetail(pjUrl, uid);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 7, e1.getMessage());
			return;
		}
	}

	public void getPjDetail(String url, int uid) {
			Document doc = null;
			try {
				doc = new GenericMyuall().getDoc(url);
			} catch (Exception e1) {
				e1.printStackTrace();
				insert2ErrDb(url, 8, e1.getMessage());
				return;
			}
			getPjDetail(doc, uid);
	}
	
	public void getPjDetail(Document doc, int uid) {
		if(null == doc) return;
		List<UnivJudgement> uts = new ArrayList<UnivJudgement>();
		Elements jels = doc.getElementsByAttributeValue("class", "a-feed");
		if(null != jels) {
			for(Element liel : jels) {
				UnivJudgement uj = new  UnivJudgement();
				// 获取头像
				Elements headEls = liel.getElementsByTag("img");
				if(null != headEls && !headEls.isEmpty()) {
					uj.setHead(headEls.first().attr("src"));
				}
				// 获取内容
				Element contentEl = liel.getElementsByAttributeValue("class","feed-content").first();
				String name = contentEl.getElementsByTag("span").first().text();
				uj.setNickname(name);
				Elements pels = contentEl.getElementsByTag("p");
				uj.setJudgeTime(pels.get(0).text());
				uj.setContent(pels.get(1).text());
				uj.setSchoolid(uid);
				uj.setSchoolname(getSchoolName(doc));
				uts.add(uj);
			}
			insert2JudgementDb(uts);
		}
	}
	
	public void getUnivTeacher(String url, int uid) {
		Document doc = null;
		try {
			doc = new GenericMyuall().getDoc(url);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 14, e1.getMessage());
			return;
		}
		if(null == doc) return;
		try {
			Element txtEl = doc.getElementsByAttributeValue("class", "yuanxiCon").first();
			Elements aels = txtEl.getElementsByTag("a");
			Map<String, String> utUrls = new HashMap<String, String>();
			for(Element ael : aels) {
				utUrls.put(ael.attr("href"), ael.text().trim());
			}
			getTeacher(utUrls, uid);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 5, e1.getMessage());
			return;
		}
	}
	public void getTeacher(Map<String, String> utUrls, int uid) {
		for(String url : utUrls.keySet()) {
			Document doc = null;
			try {
				doc = new GenericMyuall().getDoc(url);
			} catch (Exception e1) {
				e1.printStackTrace();
				insert2ErrDb(url, 15, e1.getMessage());
				return;
			}
			if(null == doc) return;
			try {
				Element txtEl = doc.getElementsByAttributeValue("class", "yuanxiCon").first();
				if(null != txtEl) {
					Elements liels = txtEl.getElementsByTag("li");
					if(null != liels && !liels.isEmpty()) {
						List<UnivTeacher> uts = new ArrayList<UnivTeacher>();
						for(Element el : liels) {
							el.getElementsByTag("a").remove();
							UnivTeacher ut = new  UnivTeacher();
							ut.setTeacherName(el.text());
							ut.setSchoolid(uid);
							ut.setFaculties(utUrls.get(url));
							ut.setSchoolname(getSchoolName(doc));
							uts.add(ut);
						}
						insert2TeacherDb(uts);
					}
				}				
			} catch (Exception e1) {
				e1.printStackTrace();
				insert2ErrDb(url, 6, e1.getMessage());
				return;
			}
		}
	}
	public void getZsContent(String url, int uid, int type) {
		Document doc = null;
		try {
			doc = new GenericMyuall().getDoc(url);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 16, e1.getMessage());
			return;
		}
		if(null == doc) return;
		try {
			Element txtEl = doc.getElementsByAttributeValue("class", "catTitleText").first();
			UnivEnro ue = new UnivEnro();
			ue.setContent(txtEl.html());
			ue.setSchoolId(uid);
			ue.setType(type);
			ue.setSchoolName(getSchoolName(doc));
			
			insert2UnivEnroDb(ue);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 4, e1.getMessage());
			return;
		}
	}
	private String getSchoolName(Document doc) {
		return doc.getElementsByAttributeValue("class", "schoolName").first().getElementsByTag("strong").first().text();
	}
	/**
	 * 获取分页列表数据
	 * @param url
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getUnivInfo(String url, int uid) {
		Document doc = null;
		try {
			doc = new GenericMyuall().getDoc(url);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 17, e1.getMessage());
			return;
		}
		if(null == doc) return;
		try {
			Elements liels = doc.getElementsByAttributeValue("class", "baseInfo clearfix").first().getElementsByTag("li");
			UnivInfoExtPo uie = new UnivInfoExtPo();
			// 获取学校名称
			Elements stEls = doc.getElementsByAttributeValue("class", "st");
			if(null != stEls && !stEls.isEmpty()) {
				Elements imgEls = stEls.first().getElementsByTag("img");
				String attrs = "";
				for(Element img:imgEls) {
					attrs += " " + img.attr("alt");
				}
				uie.setAttr(attrs);
			}
			String sn = getSchoolName(doc);
			uie.setSchoolname(sn);
			uie.setSchoolid(uid);
			for(Element el : liels) {
				if(el.text().contains("院士人数")) {
					uie.setAcademician(el.getElementsByTag("div").first().text());
				} else if (el.text().contains("重点学科")) {
					uie.setKeySubject(el.getElementsByTag("div").first().text());
				} else if (el.text().contains("博士点个数")) {
					uie.setDoctoralProgram(el.getElementsByTag("div").first().text());
				} else if (el.text().contains("硕士点个数")) {
					uie.setMaster(el.getElementsByTag("div").first().text());
				}
			}
			// 获取性别比例
			Elements sexEls = doc.getElementsByAttributeValue("class", "barGraph");
			if(null != sexEls && !sexEls.isEmpty()) {
				Element sexEl = sexEls.first();
				uie.setFemale(sexEl.getElementsByAttributeValue("class", "f").first().text());
				uie.setMale(sexEl.getElementsByAttributeValue("class", "m").first().text());
			}
			// 获取生源地数据
			String bodyStr = doc.body().html();
			if(bodyStr.contains("[[")) {
				String students = bodyStr.substring(bodyStr.indexOf("[["), bodyStr.indexOf("]]") + 2);
				uie.setStudents(students);
			}
			// 特色专业和重点专业
			Elements majorPaEls = doc.getElementsByAttributeValue("class", "modContent");
			if(null != majorPaEls && !majorPaEls.isEmpty()) {
				Elements majorEls = majorPaEls.first().getElementsByAttributeValue("class", "box txt");
				Element mel = majorEls.get(0);
				uie.setFeatureMajor(mel.html());
				mel = majorEls.get(1);
				if(null != mel) {
					Elements h3Els = mel.getElementsByTag("h3");
					Elements ulEls = mel.getElementsByTag("ul");
					for(int i=0; i< h3Els.size(); i++) {
						List<UnivKeyMajor> ukms = new ArrayList<UnivKeyMajor>();
						Elements liEls = ulEls.get(i).getElementsByTag("li");
						for(Element liel : liEls) {
							UnivKeyMajor ukm = new UnivKeyMajor();
							ukm.setSchoolid(uid);
							ukm.setSchoolname(sn);
							ukm.setType(h3Els.get(i).text());
							ukm.setMajorName(liel.text());
							ukms.add(ukm);
						}
						insert2UnivKeyMajorDb(ukms);
					}
				}
			}
			
			insert2UnivInfoDb(uie);
		} catch (Exception e1) {
			e1.printStackTrace();
			insert2ErrDb(url, 11, e1.getMessage());
			return;
		}
	}
	
	public void insert2UnivInfoDb(UnivInfoExtPo uie) {
		try {
			PreparedStatement univPs = DbUtil.getConn().prepareStatement("insert into univ_info_ext(doctoral_program,students,schoolid,feature_major,key_subject,male,schoolname,academician,female,master,attr) values(?,?,?,?,?,?,?,?,?,?,?)");
			// doctoral_program,students,schoolid,feature_major,
			// key_subject,male,schoolname,academician,female,master, attr
			univPs.setString(1, uie.getDoctoralProgram());
			univPs.setString(2, uie.getStudents());
			univPs.setInt(3, uie.getSchoolid());
			univPs.setString(4, uie.getFeatureMajor());
			univPs.setString(5, uie.getKeySubject());
			univPs.setString(6, uie.getMale());
			univPs.setString(7, uie.getSchoolname());
			univPs.setString(8, uie.getAcademician());
			univPs.setString(9, uie.getFemale());
			univPs.setString(10,uie.getMaster());
			univPs.setString(11,uie.getAttr());
			univPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void insert2JudgementDb(List<UnivJudgement> ujs) {
		try {
			PreparedStatement univPs = DbUtil.getConn().prepareStatement("insert into univ_judgement(judge_time,nickname,head,content,schoolId,schoolName) values(?,?,?,?,?,?)");
			// judge_time,nickname,head,content,schoolId,schoolName
			for(UnivJudgement uj : ujs) {
				univPs.setString(1, uj.getJudgeTime());
				univPs.setString(2, uj.getNickname());
				univPs.setString(3, uj.getHead());
				univPs.setString(4, uj.getContent());
				univPs.setInt(5, uj.getSchoolid());
				univPs.setString(6, uj.getSchoolname());
				univPs.addBatch();
			}
			univPs.executeBatch();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void insert2UnivKeyMajorDb(List<UnivKeyMajor> ukms) {
		try {
			PreparedStatement univPs = DbUtil.getConn().prepareStatement("insert into univ_key_major(schoolname,major_name,schoolid,type) values(?,?,?,?)");
			// schoolname,major_name,schoolid,type
			for(UnivKeyMajor ukm : ukms) {
				univPs.setString(1, ukm.getSchoolname());
				univPs.setString(2, ukm.getMajorName());
				univPs.setInt(3, ukm.getSchoolid());
				univPs.setString(4, ukm.getType());
				univPs.addBatch();
			}
			univPs.executeBatch();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	public void insert2TeacherDb(List<UnivTeacher> uts) {
		try {
			PreparedStatement univPs = DbUtil.getConn().prepareStatement("insert into univ_teacher(faculties,schoolId,teacher_name,schoolName) values(?,?,?,?)");
			// faculties,schoolId,teacher_name,schoolName
			for(UnivTeacher ukm : uts) {
				univPs.setString(1, ukm.getFaculties());
				 univPs.setInt(2, ukm.getSchoolid());
				univPs.setString(3, ukm.getTeacherName());
				univPs.setString(4, ukm.getSchoolname());
				univPs.addBatch();
			}
			univPs.executeBatch();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void insert2UnivEnroDb(UnivEnro ukm) {
		try {
			PreparedStatement univPs = DbUtil.getConn().prepareStatement("insert into univ_enro_gkp(content,schoolId,title,type, schoolName) values(?,?,?,?,?)");
			// content,schoolId,title,type,schoolName
			univPs.setString(1, ukm.getContent());
			univPs.setInt(2, ukm.getSchoolId());
			univPs.setString(3, ukm.getTitle());
			univPs.setInt(4, ukm.getType());
			univPs.setString(5, ukm.getSchoolName());
			univPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void insert2ErrDb(String url, int type, String prov) {
		try {
			PreparedStatement errPs = DbUtil.getConn().prepareStatement("INSERT INTO `univ_err` (`url`, `type`,`prov`) "
					+ "values(?,?,?)");
			errPs.setString(1, url);
			errPs.setInt(2, type);
			errPs.setString(3, prov);
			errPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}
